/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *  SRVGetJPGFrameOperation.m - iPhoneSRV console for Surveyor SRV-1 and SVS 
 *
 *  Created by Nick Kitchener.  Copyright (C) 2009  Surveyor Corporation 
 *            and Nick Kitchener.  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details (www.gnu.org/licenses)
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#import "SRVGetJPGFrameOperation.h"

@implementation SRVGetJPGFrameOperation

-(id)init {
	if( self = [super init] ) {
		complete = NO;
		state = READINGHEADER;
		imageSize = 0;
		request = [[SRVStreamingRequestBuffer alloc] init];
		responseHeader = [[SRVStreamingFixedLengthBinaryResponseBuffer alloc] init];
		[responseHeader setResponseLength:10];
		responseBody = nil;
		
		NSString *reqString = [NSString stringWithUTF8String:"I"];
		[request setRequestString:reqString];
	}
	return self;
}

-(void)dealloc {
	[request release];
	request = nil;
	[responseHeader release];
	responseHeader = nil;
	if(responseBody!=nil) {
		[responseBody release];
		responseBody = nil;
	}	
	[super dealloc];
}

-(void)haveBytes:(CFReadStreamRef)inputStream {
	switch(state) {
		case READINGHEADER:
			[responseHeader haveBytes:inputStream];
			if( [responseHeader isComplete]) {
				uint8_t s0,s1,s2,s3;
				uint8_t *b;
				[responseHeader getResponse:&b];
				s0 = b[6] & 0xff;
				s1 = b[7] & 0xff;
				s2 = b[8] & 0xff;
				s3 = b[9] & 0xff;
				free(b); // b was malloc'd.
				imageSize = s0 | s1<<8 | s2<<16 | s3<<24;
				if( imageSize > 512000) {
					NSLog(@"%@: Detected oversized JPG frame (%i bytes)", self, imageSize);
					imageSize = 0;
				}
				responseBody = [SRVStreamingFixedLengthBinaryResponseBuffer alloc];
				[responseBody setResponseLength:imageSize];
				state = READINGBODY;
			}
			break;
		case READINGBODY:
			[responseBody haveBytes:inputStream];
			if([responseBody isComplete]) {
				state = COMPLETE;
				complete = YES;
			}
	}
}

-(void)haveSpace:(CFWriteStreamRef)outputStream {
	[request haveSpace:outputStream];
}

-(NSData*)data {
	unsigned char *frameData; 
	[responseBody getResponse:&frameData];
	if( imageSize >0 )
		return [NSData dataWithBytesNoCopy:frameData length:imageSize freeWhenDone:YES];
	else
		return nil;
}

-(void)dumpToFile:(NSString *)filename {
	NSFileManager *fm=[NSFileManager defaultManager];
	[fm createFileAtPath:filename contents:[self data] attributes:nil];
}

+(SRVGetJPGFrameOperation*)createOperation {
	return [[SRVGetJPGFrameOperation alloc]init];
}

@end
